//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "DevReader.h"
#include "Info.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "JvHidControllerClass"
#pragma resource "*.dfm"
TMainForm *MainForm;
//---------------------------------------------------------------------------
__fastcall TMainForm::TMainForm(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::HidCtlDeviceChange(TObject *Sender)
{
  int I;
  TJvHidDevice *Dev;

  ReadBtn->Down = false;
  ReadBtnClick(this);
  if(DevListBox != NULL)
  {
    for(I = 0; I < DevListBox->Count; I++)
    {
      Dev = (TJvHidDevice *) DevListBox->Items->Objects[I];
      Dev->Free();
    }
    DevListBox->Clear();
    HistoryListBox->Clear();
    HidCtl->Enumerate();
    if(DevListBox->Items->Count > 0)
    {
      DevListBox->ItemIndex = 0;
      DevListBoxClick(this);
    }
  }
}
//---------------------------------------------------------------------------

bool __fastcall TMainForm::HidCtlEnumerate(TJvHidDevice *HidDev,
      const int Idx)
{
  int N;
  TJvHidDevice *Dev;
  AnsiString S;

  if(DevListBox != NULL)
  {
    if(HidDev->ProductName != NULL)
      N = DevListBox->Items->Add(HidDev->ProductName);
    else
      N = DevListBox->Items->Add(S.sprintf("Device VID=%04X PID=%04X",
        HidDev->Attributes.VendorID, HidDev->Attributes.ProductID));
    HidCtl->CheckOutByIndex(Dev, Idx);
    DevListBox->Items->Objects[N] = Dev;
  }
  return(true);
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::ShowRead(TJvHidDevice *HidDev,
      BYTE ReportID, const void *Data, WORD Size)
{
  WORD I;
  AnsiString Str;
  AnsiString S;
  char *P;

  P = (char *) Data;
  Str.sprintf("R %02X  ", ReportID);
  for(I = 0; I < Size; I++)
    Str += S.sprintf("%02X ", (unsigned char) P[I]);
  HistoryListBox->ItemIndex = HistoryListBox->Items->Add(Str);
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::ReadBtnClick(TObject *Sender)
{
  if(CurrentDevice != NULL)
    CurrentDevice->OnData = NULL;
  CurrentDevice = NULL;
  if(DevListBox->Items->Count > 0 && DevListBox->ItemIndex >= 0)
  {
    CurrentDevice = (TJvHidDevice *) DevListBox->Items->Objects[DevListBox->ItemIndex];
    if(ReadBtn->Down && CurrentDevice->HasReadWriteAccess)
      CurrentDevice->OnData = ShowRead;
    else
    {
      CurrentDevice->OnData = NULL;
      ReadBtn->Down = false;
    }
  }
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::DevListBoxClick(TObject *Sender)
{
  int I;
  TJvHidDevice *Dev;

  ReadBtn->Down = false;
  ReadBtnClick(this);
  HistoryListBox->Clear();
  if(Edits[0] != NULL &&
    DevListBox->Items->Count > 0 && DevListBox->ItemIndex >= 0)
  {
    Dev = (TJvHidDevice *) DevListBox->Items->Objects[DevListBox->ItemIndex];
    for(I = 0; I < 64; I++)
      Edits[I]->Visible = false;
    for(I = 0; I < Dev->Caps.OutputReportByteLength - 1; I++)
      Edits[I]->Visible = true;
    WriteBtn->Enabled = Dev->Caps.OutputReportByteLength != 0;
  }
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::SaveBtnClick(TObject *Sender)
{
  ForceCurrentDirectory = true;
  if(SaveDialog->Execute())
    HistoryListBox->Items->SaveToFile(SaveDialog->FileName);
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::FormActivate(TObject *Sender)
{
  int I;
  int J;
  TEdit *E;

  if(Edits[0] != NULL)
    return;
  Edits[0] = Edit1;
  for(I = 1; I < 64; I++)
    Edits[I] = new TEdit(this);
  for(J = 0; J < 4; J++)
    for(I = 0; I < 16; I++)
    {
      E = Edits[J*16 + I];
      E->Visible  = false;
      E->Left     = Edit1->Left + I*(Edit1->Width+2);
      E->Top      = Edit1->Top  + J*(Edit1->Height+2);
      E->Width    = Edit1->Width;
      E->Anchors  = Edit1->Anchors;
      if(E->Parent == NULL)
        E->Parent = Edit1->Parent;
      E->TabOrder = Edit1->TabOrder + J*16 + I;
    }
  DevListBoxClick(this);
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::WriteBtnClick(TObject *Sender)
{
  unsigned int I;
  unsigned char Buf[65];
  unsigned int Written;
  unsigned int ToWrite;
  AnsiString Str;
  AnsiString S;

  if(CurrentDevice != NULL)
  {
    Buf[0] = StrToIntDef("$" + ReportID->Text, 0);
    ReportID->Text = Str.sprintf("%02X", Buf[0]);
    ToWrite = CurrentDevice->Caps.OutputReportByteLength;
    for(I = 1; I < ToWrite; I++)
    {
      Buf[I] = StrToIntDef("$" + Edits[I-1]->Text, 0);
      Edits[I-1]->Text = Str.sprintf("%02X", Buf[I]);
    }
    CurrentDevice->WriteFile(Buf, ToWrite, Written);
    Str.sprintf("W %02X  ", Buf[0]);
    for(I = 1; I < Written; I++)
      Str += S.sprintf("%02X ", Buf[I]);
    HistoryListBox->ItemIndex = HistoryListBox->Items->Add(Str);
  }
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::InfoBtnClick(TObject *Sender)
{
  TInfoForm *Info;

  if(DevListBox->Items->Count > 0 && DevListBox->ItemIndex >= 0)
  {
    Info = new TInfoForm(this);
    Info->Dev = (TJvHidDevice *) DevListBox->Items->Objects[DevListBox->ItemIndex];
    Info->ShowModal();
    delete Info;
  }
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::HidCtlDeviceDataError(TJvHidDevice *HidDev,
      DWORD Error)
{
  HistoryListBox->ItemIndex = HistoryListBox->Items->Add("READ ERROR: " + SysErrorMessage(Error));
}
//---------------------------------------------------------------------------

